﻿// Copyright (C) 2009 Choonghwan Lee (linjus.lee@gmail.com)
//
// This file is part of amanda.
//
// amanda is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// amanda is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with amanda. If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Serialization;
using System.Xml;

namespace manager
{
	public static class Configuration
	{
		private static readonly string basedirectory = @".\";
		public static readonly string LibraryDirectory = basedirectory + "Libraries";

		private static ConfigInfo config;
		public static ConfigInfo Config
		{ get { return config; } }

		private static List<DeviceInfo> devices;
		private static List<LibraryInfo> libraries;

		public static List<DeviceInfo> Devices
		{ get { return devices; } }

		public static List<LibraryInfo> Libraries
		{ get { return libraries; } }

		public static void Initialize()
		{
			InitializeConfig();
			InitializeDevice();
			InitializeLibrary();

			foreach (LibraryInfo lib in libraries) {
				if (!lib.Validate())
					throw new Exception("Library '" + lib.Name + "' has invalid Device name '" + lib.DeviceName + "'");
			}
		}

		public struct ConfigInfo
		{
			public string TempDirectory;
			public string FLAC_to_WAVE;
			public string OGG_to_WAVE;
			public string PCM_to_MP3;
			public string WAVE_to_MP3;
		}

		private static bool GetConfigItem(string line, string name, out string value)
		{
			value = null;
			if (!line.StartsWith(name + '=')) return false;

			value = line.Substring(name.Length + 1);
			value = value.Trim();
			return true;
		}

		private static void InitializeConfig()
		{
			string configfile = basedirectory + "config";
			using (TextReader reader = new StreamReader(configfile)) {
				for (; ; ) {
					string line = reader.ReadLine();
					if (line == null) break;
					if (line.StartsWith("\"")) continue;
					if (line.Trim().Length == 0) continue;

					string value;
					if (GetConfigItem(line, "TempDirectory", out value)) config.TempDirectory = value;
					else if (GetConfigItem(line, "flac_wav", out value)) config.FLAC_to_WAVE = value;
					else if (GetConfigItem(line, "ogg_wav", out value)) config.OGG_to_WAVE = value;
					else if (GetConfigItem(line, "pcm_mp3", out value)) config.PCM_to_MP3 = value;
					else if (GetConfigItem(line, "wav_mp3", out value)) config.WAVE_to_MP3 = value;
					else {
						throw new Exception("Configuration file '" + configfile + "' has invalid line: " + line);
					}
				}
			}

			if (!config.TempDirectory.EndsWith("\\"))
				config.TempDirectory = config.TempDirectory + "\\";
		}

		private static void InitializeDevice()
		{
			devices = new List<DeviceInfo>();

			XmlSerializer xs = new XmlSerializer(typeof(DeviceInfo));
			DirectoryInfo dirinfo = new DirectoryInfo(basedirectory + "Devices");
			foreach (FileInfo fi in dirinfo.GetFiles("*.xml")) {
				try {
					using (XmlTextReader reader = new XmlTextReader(fi.FullName)) {
						DeviceInfo instance = (DeviceInfo)xs.Deserialize(reader);
						devices.Add(instance);
					}
				}
				catch (Exception) {
				}
			}
		}

		private static void InitializeLibrary()
		{
			libraries = new List<LibraryInfo>();

			XmlSerializer xs = new XmlSerializer(typeof(LibraryInfo));
			DirectoryInfo dirinfo = new DirectoryInfo(LibraryDirectory);
			foreach (FileInfo fi in dirinfo.GetFiles("*.xml")) {
				try {
					using (XmlTextReader reader = new XmlTextReader(fi.FullName)) {
						LibraryInfo instance = (LibraryInfo)xs.Deserialize(reader);
						libraries.Add(instance);
					}
				}
				catch (Exception) {
				}
			}
		}
	}

	public static class Global
	{
		public static MainWindow MainWindow;
	}
}
